package com.grm.distributed.lock.service;

import com.grm.distributed.lock.common.Result;
import com.grm.distributed.lock.mapper.ProductMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

/**
 * redis基于setnx指令实现分布式锁-重试（循环获取）
 */
@Slf4j
@Service
public class ProductService7 {
    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public Result sell() {
        // 1. 执行setnx加锁,setIfPresent：存在就设置(setxx)，setIfAbsent：不存在就设置(setnx)
        // 2. 获取锁失败，重试:循环重试
        while (!stringRedisTemplate.opsForValue().setIfAbsent("lock", "111")) {
            try {
                Thread.sleep(30);
                log.info("循环重试获取锁中");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        try {
            // 3. 查库存
            String productCountStr = stringRedisTemplate.opsForValue().get("product_count");
            Integer count = Integer.valueOf(productCountStr);
            // 4. 扣减库存
            if (count > 0) {
                count = count - 1;
            }
            log.info("product current count = {}", count);
            stringRedisTemplate.opsForValue().set("product_count", String.valueOf(count));
        } finally {
            // 5. 解锁
            stringRedisTemplate.delete("lock");
        }
        return Result.success();
    }
}
